#!/usr/env/bin python
"""
:mod:`pynchon.util.app`
=======================

Creating and using command-line applications.
"""
from optparse import OptionParser
from tempfile import NamedTemporaryFile
from subprocess import Popen, PIPE
from os import devnull, path

def run_app(app, args=None, stdin=None, **kwargs):
    """
    A simple wrapper around ``subprocess.Popen`` executes a command-line 
    application with the given arguments and returns a 3-tuple of 
    ``(returncode, stdout, stderr)``.
    
    Arguments:
    
        - app (``str``) The name of the application to run.
        - args (``sequence``) [default: None] A sequence of arguments to the 
          program.
        - stdin (``file``) An open for reading file handle.
        
    Additional keyworded arguments are passed to the ``subprocess.Popen`` 
    constructor. 
    """
    args = args or []
    args.insert(0, app)
    kwargs['stdout'] = kwargs.get('stdout', None) or PIPE
    kwargs['stderr'] = kwargs.get('stderr', None) or PIPE
    app = Popen(args=args, stdin=stdin, **kwargs)
    stdout, stderr = app.communicate(stdin)
    code = app.wait()
    return (code, stdout, stderr)

def report_err(command, args, code, stdout='', stderr='', kwargs=''):
    print 'Failure:'
    print command, (args or ''), (kwargs or '')
    print 'failed with code: %s' % code
    print 'STDOUT:', stdout
    print 'STDERR:', stderr

def sh(command, **kwargs):
    """
    Executes command-line in the shell. No ``stdin``, ``stdout`` and ``stderr``
    go to ``/dev/null`` and the command is executed via the default shell.
    Additional keyworded arguments are passed to ``Popen``.
    
    Arguments:
    
        - command (``str`` or ``sequence``) This command line will be executed.
          See the documentation for "args" in ``subprocess.Popen``. 
    """
    NULL = open(devnull, 'w')
    app = Popen(command, stdin=None, stdout=NULL, stderr=NULL, \
                                        shell=True, **kwargs)
    app.communicate()
    code = app.wait()
    return code
    
def tmp_file(filepath=None, overwrite=False):
    """
    Creates a temporary file and returns a file handle. If "filepath" is given 
    it will be created or overwritten if overwrite is ``True``, else a temporary
    file will be created. The name of the file is accessible from the "name"
    attribute of the file handle, the file ceases to exist if it is closed or
    the handle garbage collected.
    
    Arguments:
    
        - filepath (``str``) [default: ``None``] Path to the file. 
        - overwrite (``bool``) [default: ``False``] Should the destination be
          overwritten if it exists? (ignored if "filepath" is ``None``)
    """
    if filepath:
        if path.exists(filepath) and not overwrite:
            raise ValueError('The path: %s exists!' % filepath)
        fh = open(filepath, 'w+b')
    else:
        fh = NamedTemporaryFile()
    return fh
         
def opt_parse(app_name, version, usage):
    parser = OptionParser(usage=usage, version="%s %s" % (app_name, version))
    return parser
    




     
